using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using AutoClick.native;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;

namespace AutoClick.utils;

public struct Rect(int left, int top, int right, int bottom)
{
    public readonly int Left = left;
    public readonly int Top = top;
    public readonly int Right = right;
    public readonly int Bottom = bottom;
}

public struct MatchResult
{
    public double ResultValue;
    public Mat Src;
    public string DstIcon;
    public Mat Dst;
    public Mat ResultMat;
    public Point DstPoint;
    public double MaxVal, MinVal;
    public Point MaxLoc, MinLoc;
}

public class CaptureUtil
{
    
    // 定义常量
    public const int SW_RESTORE = 9; // 恢复窗口（如果最小化）
    public const int SW_SHOW = 5; // 显示窗口

    // 获取窗口句柄
    public static IntPtr GetWindowHandle(string processName)
    {
        Process[] processes = Process.GetProcessesByName(processName);
        if (processes.Length == 0)
        {
            throw new Exception($"没有找到名为 {processName} 的进程");
        }

        return processes[0].MainWindowHandle;
    }

    public static void DrawRectangle(Mat image, Mat template, Point topLeft)
    {
        // 获取模板的宽度和高度
        int width = template.Cols;
        int height = template.Rows;

        // 定义矩形框的颜色和厚度
        MCvScalar color = new MCvScalar(0, 255, 0); // 绿色
        int thickness = 2;

        // 计算矩形框的右下角位置
        // Point bottomRight = new Point(topLeft.X + width, topLeft.Y + height);

        // 在图像上绘制矩形框
        CvInvoke.Rectangle(image, new Rectangle(topLeft, template.Size), color, thickness);
    }

    public static Mat BitmapToEmguMat(Bitmap bitmap)
    {
        // 将 Bitmap 编码为 PNG 格式的字节数组
        byte[] buffer;
        using (MemoryStream ms = new MemoryStream())
        {
            bitmap.Save(ms, ImageFormat.Png);
            buffer = ms.ToArray();
        }

        // 使用 Imdecode 将字节数组解码为 Mat
        Mat dst = new Mat();
        CvInvoke.Imdecode(buffer, ImreadModes.AnyColor, dst);

        return dst;
    }

    public static MatchResult Match(Mat src, String iconFileName)
    {
        return Match(src, iconFileName, CvInvoke.Imread(iconFileName, ImreadModes.AnyColor), false);
    }

    public static MatchResult Match(Mat src, String dstIcon, Mat dst, bool isDstFromCache)
    {
        MatchResult matchResult = new MatchResult
        {
            DstIcon = dstIcon.Contains('/') ? dstIcon[(dstIcon.LastIndexOf('/') + 1)..] : dstIcon,
        };

        // 转换为灰度图像（可选，提高匹配速度）
        Mat srcGray = new Mat();
        CvInvoke.CvtColor(src, srcGray, ColorConversion.Bgr2Gray);
        Mat iconGray;
        if (isDstFromCache)
        {
            iconGray = dst;
        }
        else
        {
            iconGray = new Mat();
            CvInvoke.CvtColor(dst, iconGray, ColorConversion.Bgr2Gray);
            matchResult.Dst = iconGray;
        }

        // 使用模板匹配
        Mat result = new Mat();
        CvInvoke.MatchTemplate(srcGray, iconGray, result, TemplateMatchingType.CcoeffNormed);

        // 找到最佳匹配位置
        double minVal = 0, maxVal = 0;
        Point minLoc = new(), maxLoc = new();
        CvInvoke.MinMaxLoc(result, ref minVal, ref maxVal, ref minLoc, ref maxLoc);

        matchResult.MinVal = minVal;
        matchResult.MaxVal = maxVal;
        matchResult.MinLoc = minLoc;
        matchResult.MaxLoc = maxLoc;
        matchResult.ResultMat = result;
        matchResult.ResultValue = maxVal;

        return matchResult;
    }

    public static Point GetAbsPoint(Rect rect, MatchResult result)
    {
        int x = rect.Left + result.MaxLoc.X + 10;
        int y = rect.Top + result.MaxLoc.Y + 10;

        return new Point(x, y);
    }
}